package session

import (
	"log"
	"sync"
	"time"
	"video_server/dbops"
	"video_server/defs"
	"video_server/utils"
)

/* session两个作用：
1) 服务起来时将DB中的session数据加载到api的cache中
2) 用户登录时进行session验证，生成session
3) session过期状态
*/

var sessionMap *sync.Map

func init() {
	sessionMap = &sync.Map{}
}

func nowInMilli() int64 {
	return time.Now().UnixNano() / 1000000
}

func deleteExpiredSession(sid string) {
	// 从缓存中删除
	sessionMap.Delete(sid)
	//	从DB中删除
	err := dbops.DeleteSession(sid)
	if err != nil {
		log.Fatal("Delete session err:", err)
	}
}

func LoadSessionFromDB() {
	r, err := dbops.RetrieveAllSessions()
	if err != nil {
		return
	}
	// 将查询出来的sessions写入map
	r.Range(func(k, v interface{}) bool {
		ss := v.(*defs.SimpleSession)
		sessionMap.Store(k, ss)
		return true
	})
}

func GenerateNewSessionId(un string) string {
	id, _ := utils.NewUUID()
	ct := time.Now().UnixNano() / 1000000
	ttl := ct * 30 * 60 * 1000 // 过期时间30min

	ss := &defs.SimpleSession{
		Username: un,
		TTL:      ttl,
	}
	sessionMap.Store(id, ss)
	err := dbops.InsertSession(id, ttl, un)
	if err != nil {
		log.Fatal(err)
	}
	return id
}

func IsSessionExpired(sid string) (string, bool) {
	ss, ok := sessionMap.Load(sid)
	if ok {
		ct := nowInMilli()
		if ss.(*defs.SimpleSession).TTL < ct {
			deleteExpiredSession(sid)
			return "", true
		}
		return ss.(*defs.SimpleSession).Username, false
	}
	return "", true
}
